<template>
  <div :class="className">
    <el-input v-model="propValue" readonly class="wft-w-100" placeholder="请选择变量" size="small">
      <template #prepend>
        <el-select v-model="propValue" placeholder="选择变量" filterable :style="{width: selectWidth + 'px'}" clearable>
          <el-option v-for="(item, index) in panelJson.data" :key="item.variable" :value="item.variable">
            <el-row>
              <el-col :span="20">
                <span>{{ item.desc ? `${item.variable}（${item.desc}）` : item.variable }}</span>
              </el-col>
              <el-col :span="4">
                <el-button link size="small" @click.stop="edit(item)" icon="Edit" />
                <el-button link size="small" @click.stop="remove(item, index)" icon="Delete" />
              </el-col>
            </el-row>
          </el-option>
        </el-select>
      </template>
      <template #append>
        <el-popover :visible="visible" placement="top" :width="260" popper-class="wft-custom-popover">
          <div class="wft-custom-popover-herder">
            <h4>添加页面变量</h4>
          </div>
          <el-form ref="pageDataFormRef" size="small" :model="pageDataItem" label-position="right" label-width="90px">
            <el-row>
              <el-col :span="24">
                <el-form-item prop="variable" :rules="[{ required: true, message: '请输入变量名', trigger: 'blur' }]">
                  <template #label>
                    <span>变量名称</span>
                    <el-tooltip effect="dark" content="页面中定义的变量" placement="top">
                      <i class="wft-icon-tooltip margin-left-4" />
                    </el-tooltip>
                  </template>
                  <el-input v-model="pageDataItem.variable" placeholder="请输入" class="wft-w-100" :disabled="method == 'edit'" />
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item prop="type" :rules="[{ required: true, message: '请选择变量类型', trigger: 'blur' }]">
                  <template #label>
                    <span>变量类型</span>
                    <el-tooltip effect="dark" content="用于设置变量初始值" placement="top">
                      <i class="wft-icon-tooltip margin-left-4" />
                    </el-tooltip>
                  </template>
                  <el-select v-model="pageDataItem.type" class="wft-w-100" @change="typeChange">
                    <el-option label="string" value="string" />
                    <el-option label="number" value="number" />
                    <el-option label="boolean" value="boolean" />
                    <el-option label="object" value="object" />
                    <el-option label="array" value="array" />
                    <el-option label="null" value="null" />
                    <el-option label="undefined" value="undefined" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item>
                  <template #label>
                    <span>变量描述</span>
                    <el-tooltip effect="dark" content="页面中定义的变量描述/注释" placement="top">
                      <i class="wft-icon-tooltip margin-left-4" />
                    </el-tooltip>
                  </template>
                  <el-input v-model="pageDataItem.desc" placeholder="请输入" class="wft-w-100" />
                </el-form-item>
              </el-col>
              <el-col v-if="pageDataItem.type && pageDataItem.type !== 'undefined' && pageDataItem.type !== 'null'" :span="24">
                <el-form-item>
                  <template #label>
                    <span>变量值</span>
                    <el-tooltip effect="dark" content="组件中定义的变量默认初始值" placement="top">
                      <i class="wft-icon-tooltip margin-left-4" />
                    </el-tooltip>
                  </template>
                  <el-input v-if="pageDataItem.type === 'string'" v-model="pageDataItem.value" size="small" placeholder="请输入" class="wft-w-100" />
                  <el-input-number v-else-if="pageDataItem.type === 'number'" v-model="pageDataItem.value" size="small" placeholder="请输入" class="wft-w-100" />
                  <el-switch v-else-if="pageDataItem.type === 'boolean'" v-model="pageDataItem.value" active-text="true" inactive-text="false" />
                  <template v-else-if="pageDataItem.type === 'array' || pageDataItem.type === 'object'">
                    <MonacoEditor
                      :model-value="valueStr"
                      :height="180"
                      language="json"
                      :editorOption="{ lineNumbers: 'off', theme: 'vs' }"
                      @update:model-value="val => updateValue = val"
                    />
                    <el-button size="small" type="primary" plain @click="updateData" class="wft-w-100 margin-top-8">更新数据</el-button>
                  </template>
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
          <div class="wft-custom-popover-footer">
            <el-button size="small" plain @click="visible = false">取消</el-button>
            <el-button size="small" plain type="primary" @click="confirm">确定</el-button>
          </div>
          <template #reference>
            <el-button icon="Plus" @click="add" />
          </template>
        </el-popover>
      </template>
    </el-input>
  </div>
</template>
<script setup lang='ts'>
import { panelJsonDefault } from 'generator/index/Layout/ConfigPanel/widget/default'
import { computed, ref } from 'vue';
import type { FormInstance } from 'element-plus'
import { useMessage } from '@/hooks';
import { useVariableRemove } from 'generator/hooks'
import MonacoEditor from '../MonacoEditor/index.vue'

const props = withDefaults(defineProps<{
  panelJson?: TPanel,
  className?: string,
  selectWidth?: number
}>(), {
  panelJson: () => panelJsonDefault,
  className: 'wft-w-95',
  selectWidth: 80
})

const visible = ref(false)
let method = 'add'
const pageDataItem = ref<IPageData>({
  variable: '',
  desc: '',
  type: 'string',
  value: ''
})
const pageDataFormRef = ref<FormInstance>()

let updateValue = ''
const valueStr = computed(() => {
  if(pageDataItem.value.type == 'array' || pageDataItem.value.type == 'object') {
    return JSON.stringify(pageDataItem.value.value)
  }
  return ''
})

function updateData () {
  try {
    pageDataItem.value.value = JSON.parse(updateValue)
    useMessage().success('更新成功')
  } catch (e) {
    console.log(e)
    useMessage().error('更新失败，请检查数据格式')
  }
}

const propValue = defineModel<string>('modelValue', { default: '' })

const { remove } = useVariableRemove(props.panelJson)

// 添加变量
function add() {
  method = 'add'
  initPageDataItem()
  visible.value = true
}

// 初始化
function initPageDataItem() {
  pageDataItem.value = {
    variable: '',
    desc: '',
    type: 'string',
    value: ''
  }
}

// 修改变量
function edit(item: IPageData) {
  method = 'edit'
  pageDataItem.value = JSON.parse(JSON.stringify(item))
  visible.value = true
}

// 保存
function confirm() {
  pageDataFormRef.value!.validate(valid => {
    if (valid) {
      if(method == 'add') {
        if(props.panelJson.data.findIndex(item => item.variable === pageDataItem.value.variable) >= 0) {
          return useMessage().success('变量名已存在')
        }
        props.panelJson.data.push(JSON.parse(JSON.stringify(pageDataItem.value)))
        useMessage().success('添加成功')
        propValue.value = pageDataItem.value.variable
      } else if(method == 'edit') {
        const index = props.panelJson.data.findIndex(item => item.variable === pageDataItem.value.variable)
        props.panelJson.data[index] = JSON.parse(JSON.stringify(pageDataItem.value))
        useMessage().success('修改成功')
      }
      visible.value = false
    }
  })
}

// 类型切换
function typeChange () {
  const map = <{[k: string]: any}>{
    string: '',
    number: 0,
    boolean: false,
    object: {},
    array: [],
    null: null,
    undefined: undefined
  }
  pageDataItem.value.value = map[pageDataItem.value.type]
}
</script>
<style scoped>
.wft-custom-popover-herder {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 12px;
  border-bottom: 1px solid #e4e7ed;
  padding-bottom: 5px;
}

.wft-custom-popover-footer {
  width: 100%;
  text-align: right;
}

.wft-icon-tooltip {
  font-size: 12px;
}
</style>